package com.hwq.sql.tool.generate;

import com.hwq.sql.tool.enums.DataType;
import com.hwq.sql.tool.model.Config;
import com.hwq.sql.tool.model.ExcelTemp;
import com.hwq.sql.tool.model.Field;
import com.hwq.sql.tool.model.Table;
import com.hwq.sql.tool.utils.FileUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractGenerate {

    protected String tablePath;    // 建表脚本
    protected String insertPath;   // 初始化脚本
    protected Config config;       // 配置项
    protected Configuration cfg;   // FREEMARKER 模板配置项

    public AbstractGenerate(Config config, Configuration cfg) {
        String rootPath = config.getRootPath() + getDbType() + config.getVersion() + File.separator;
        this.tablePath = rootPath + "table.sql";
        this.insertPath = rootPath + "insert.sql";
        this.config = config;
        this.cfg = cfg;
    }

    /**
     * 获取数据库类型
     */
    protected abstract String getDbType();

    /**
     * 获取 FREEMARKER 模板
     */
    protected abstract Template getFtl() throws IOException;

    /**
     * 设置数据类型
     */
    protected abstract String getDataType(DataType dataType);

    /**
     * 构造 SQL 脚本
     */
    public void buildSql() {
        ExcelTemp excelTemp = new ExcelTemp(config);
        Map<String, Object> map = new HashMap<>();
        List<Table> tables = excelTemp.getTables();
        setDataType(tables);
        map.put("tables", tables);
        File tableFile = FileUtil.getFile(tablePath);
        try (
                OutputStream fos = new FileOutputStream(tableFile);
                Writer osw = new OutputStreamWriter(fos)
        ) {
            Template ftl = getFtl();
            ftl.process(map, osw);
        } catch (IOException | TemplateException ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 处理数据库类型
     */
    private void setDataType(List<Table> tables) {
        for (Table table : tables) {
            for (Field field : table.getFieldList()) {
                DataType dataType = DataType.get(field.getDataType(), config.getDatabase());
                field.setDataType(getDataType(dataType));
            }
        }
    }


}
